package com.dlc.shop.distribution.common.service.impl;

import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.bean.enums.OfflineHandleEventStatus;
import com.dlc.shop.bean.enums.OfflineHandleEventType;
import com.dlc.shop.bean.model.OfflineHandleEvent;
import com.dlc.shop.bean.model.OrderItem;
import com.dlc.shop.bean.model.ProdLang;
import com.dlc.shop.bean.model.Product;
import com.dlc.shop.bean.param.OfflineHandleEventAuditParam;
import com.dlc.shop.common.bean.PaySettlementConfig;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.util.Arith;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.common.util.PrincipalUtil;
import com.dlc.shop.distribution.common.constants.DistributionProdStateEnum;
import com.dlc.shop.distribution.common.dao.DistributionProdMapper;
import com.dlc.shop.distribution.common.dao.DistributionUserMapper;
import com.dlc.shop.distribution.common.dto.DistributionProdDto;
import com.dlc.shop.distribution.common.model.DistributionProd;
import com.dlc.shop.distribution.common.model.DistributionProdLog;
import com.dlc.shop.distribution.common.model.DistributionUser;
import com.dlc.shop.distribution.common.po.DistributionProdPO;
import com.dlc.shop.distribution.common.service.DistributionProdService;
import com.dlc.shop.distribution.common.vo.DistributionAwardDataVO;
import com.dlc.shop.manager.impl.LangManager;
import com.dlc.shop.service.OfflineHandleEventService;
import com.dlc.shop.service.SysConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lgh on 2019/04/01.
 */
@Service
@RequiredArgsConstructor
public class DistributionProdServiceImpl extends ServiceImpl<DistributionProdMapper, DistributionProd> implements DistributionProdService {

    private final DistributionProdMapper distributionProdMapper;

    private final DistributionUserMapper distributionUserMapper;

    private final OfflineHandleEventService offlineHandleEventService;

    private final SysConfigService sysConfigService;

    private final LangManager langManager;

    @Override
    public IPage<DistributionProd> distributionProdsPage(Page page, DistributionProd distributionProd, String prodName) {
        IPage<DistributionProd> distributionProdPage = distributionProdMapper.distributionProdsPage(page, distributionProd, prodName);
        List<Product> products = new ArrayList<>();
        List<Product> prodList = distributionProdPage.getRecords().stream().map(DistributionProd::getProduct).filter(Objects::nonNull).collect(Collectors.toList());
        langManager.getProdLang(prodList);
        return distributionProdPage;
    }

    @Override
    public List<DistributionProdDto> distributionProdDtoPage(Page<DistributionProdDto> page, String prodName, Integer sort, Integer orderBy, DistributionUser distributionUser) {
        IPage<DistributionProdPO> distributionProdPoPage = distributionProdMapper.distributionProdPoPage(page, prodName, sort, orderBy, I18nMessage.getLang());
        List<Long> ids = distributionProdPoPage.getRecords().stream().map(DistributionProdPO::getProdId).filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, ProdLang> prodLangMap = langManager.getProdLangMap(ids);
        // 获取商品的分佣金额，或分佣奖励
        List<DistributionProdDto> distributionProdDtoList = new ArrayList<>();
        for (DistributionProdPO distributionProdPo : distributionProdPoPage.getRecords()) {

            //po转dto
            DistributionProdDto distributionProdDto = new DistributionProdDto();
            distributionProdDto.setProdId(distributionProdPo.getProdId());
            distributionProdDto.setProdName(distributionProdPo.getProdName());
            distributionProdDto.setProdType(distributionProdPo.getProdType());
            distributionProdDto.setPic(distributionProdPo.getPic());
            distributionProdDto.setPrice(distributionProdPo.getPrice());
            distributionProdDto.setAwardProportion(distributionProdPo.getAwardProportion());
            distributionProdDto.setAwardNumber(distributionProdPo.getAwardNumbers());
            distributionProdDto.setParentAwardNumber(distributionProdPo.getParentAwardNumbers());
            distributionProdDto.setShopId(distributionProdPo.getShopId());
            ProdLang prodLang = prodLangMap.get(distributionProdPo.getProdId());
            if (Objects.nonNull(prodLang)) {
                distributionProdDto.setProdName(prodLang.getProdName());
            }
            //添加到集合中
            distributionProdDtoList.add(distributionProdDto);
        }


        return distributionProdDtoList;
    }

    /**
     * 根据分销商品设置、分享人id，计算奖励数据
     *
     * @param distributionProdPo
     * @param distributionUserId
     * @param orderItem
     * @return
     */
    @Override
    public DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPo, Long distributionUserId, OrderItem orderItem) {
        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();
        distributionAwardDataVO.setAwardNumber(distributionProdPo.getAwardNumbers());
        distributionAwardDataVO.setParentAwardNumber(distributionProdPo.getParentAwardNumbers());
        distributionAwardDataVO.setAwardProportion(distributionProdPo.getAwardProportion());
        if (Objects.nonNull(distributionAwardDataVO.getAwardProportion())) {
            //如果计算为按比例计算，则转化为具体金额
            if(Objects.equals(distributionAwardDataVO.getAwardProportion(), 0)) {
                distributionAwardDataVO.setAwardProportion(0);
                //根据商品价格,计算得到的佣金
                distributionAwardDataVO.setAwardNumber(Arith.div(Arith.mul(distributionProdPo.getPrice(),distributionAwardDataVO.getAwardNumber()),100, 2));
                distributionAwardDataVO.setParentAwardNumber(Arith.div(Arith.mul(distributionProdPo.getPrice(),distributionAwardDataVO.getParentAwardNumber()), 100, 2));
            } else {
                distributionAwardDataVO.setAwardNumber(Arith.roundByBanker(Arith.mul(distributionAwardDataVO.getAwardNumber(),orderItem.getProdCount()),2));
                distributionAwardDataVO.setParentAwardNumber(Arith.roundByBanker(Arith.mul(distributionAwardDataVO.getParentAwardNumber(),orderItem.getProdCount()),2));
            }
        }
        return distributionAwardDataVO;

    }


    @Override
    @Cacheable(cacheNames = "DistributionProdPO", key = "#prodId")
    public DistributionProdPO getDistributionProdPoByProdId(Long prodId) {
        return distributionProdMapper.getDistributionProdPoByProdId(prodId);
    }

    @Override
    @CacheEvict(cacheNames = "DistributionProdPO", key = "#prodId")
    public void removeDistributionProdPoCacheByProdId(Long prodId) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(DistributionProd distributionProd, String offlineReason, Long sysUserId) {
        List<Integer> statusIds = new ArrayList<>();
        statusIds.add(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        statusIds.add(OfflineHandleEventStatus.APPLY_BY_SHOP.getValue());
        long count = offlineHandleEventService.count(new LambdaQueryWrapper<OfflineHandleEvent>()
                .eq(OfflineHandleEvent::getHandleType, OfflineHandleEventType.DISTRIBUTION_PROD.getValue())
                .eq(OfflineHandleEvent::getHandleId, distributionProd.getDistributionProdId())
                .in(OfflineHandleEvent::getStatus, statusIds));
        if(count > 0){
            throw new YamiShopBindException("yami.platform.prod.offline.check");
        }
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setShopId(distributionProd.getShopId());
        offlineHandleEvent.setHandleId(distributionProd.getDistributionProdId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.DISTRIBUTION_PROD.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);

        // 更新活动状态为下线
        if (distributionProdMapper.updateState(distributionProd.getDistributionProdId(), DistributionProdStateEnum.OFFLINE.getValue()) < 0) {
            // 更新活动商品失败
            throw new YamiShopBindException("yami.activity.prod.update.error");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditDistributionProd(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新活动状态
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.PUT_OFF.getValue());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.OFFLINE.getValue());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long distributionProdId, String reapplyReason) {
        // 更新活动为待审核状态
        distributionProdMapper.updateState(distributionProdId, DistributionProdStateEnum.WAIT_AUDIT.getValue());

        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }

    @Override
    public IPage<DistributionProdLog> getDistributionProdLogPage(PageParam<DistributionProdLog> page, DistributionProdLog distributionProdLog) {
        PaySettlementConfig config = sysConfigService.getSysConfigObject(Constant.PAY_SETTLEMENT_CONFIG, PaySettlementConfig.class);
        IPage<DistributionProdLog> logPage = distributionProdMapper.getDistributionProdLogPage(page, distributionProdLog, config.getPaySettlementType());
        for (DistributionProdLog record : logPage.getRecords()) {
            if(StrUtil.isNotBlank(record.getUserMobile())) {
                record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString());
            }
            if (PrincipalUtil.isMobile(record.getNickName())) {
                record.setNickName(PhoneUtil.hideBetween(record.getNickName()).toString());
            }
        }
        return logPage;
    }

    @Override
    public List<DistributionProd> listByOrderItems(List<OrderItem> orderItems) {
        return distributionProdMapper.listByOrderItems(orderItems);
    }

    @Override
    public Boolean isStateByProdId(Long prodId, Integer state) {
        DistributionProd distributionProd = distributionProdMapper.selectOne(new LambdaQueryWrapper<DistributionProd>().eq(DistributionProd::getProdId, prodId).eq(DistributionProd::getState, state));
        return Objects.nonNull(distributionProd);
    }

    @Override
    public int updateState(Long distributionProdId, Integer status) {
        return distributionProdMapper.updateState(distributionProdId,status);
    }

}
